迷宫问题--压栈、回溯、全部路径、最短路径

迷宫问题

用循环模拟压栈来实现迷宫问题

  • 我们可以用一个二维数组(N*N)来表示迷宫,1表示路,0表示墙,我们把下方当成迷宫入口,出口为数组右方,此迷宫有两个出口。
    这里写图片描述

  • 需要建立一个结构体arg用来存放关于迷宫(二维数组)的信息。也就是存二维数组的两个下标

  • 然后创建关于用来压栈的结构体

  • 迷宫每个节点都有4个方向可以探寻。碰到墙壁(0)或者边界则此路不通
    传迷宫的入口进去也就是数组gMaze[5][2]的信息,这时我们需要传5,2,然后再传一个整型用来标记迷宫的状态,用arg.att表示。

arg.att:这个状态用来标记我们是否试走过 此处 的四个方位,因为0是墙,1是路,所以我们用2来表示我们试过此处的左边能不能通行,3用来表示此处的上方是否通行,4表示右边,5表示下边。用6来表示出口。假如说试过左边不能走,我们就将标记改为3,让他继续试上边能不能走。

进入循环

进入循环之前,先将5,2以及初始标记值2压进栈。

迷宫出口条件:

结束条件为,如果目标走到数组右侧,也就是gMaze[ ][N-1]结束,然后跳出整个循环。
(如果在这里结束,我们则只能找到一条通路,我们让while循环来决定是否结束,此时便能找出多个出口)

先看下面的此处坐标各个方向能不能走,再看下面这段话:

  • 保存每一条路:
    如果他能走到这里就说明是一条通路,这时数组里的数据就是走过的一条路径,这时我们创建一个指针数组,每次走到这里,我们就动态开辟一块内存。复制这个数组到该内存中,然后让指针数组来保存这个内存地址,然后让指针数组的下标++,实现保存每一种通路

  • 求出最短路径:
    我们动态开辟一块内存用来保存gMaze数组,一个变量k=0; 判断条件为(如果k==0 || 栈的大小 <=k) 我们就将此时的数组保存起来,然后将k更新为栈的大小值。
    这样我们就会将第一次的数组保存起来,后面不断的将栈最小时候的数组替换到当前动态开辟的内存中,实现最短路径

保存栈顶元素

然后我们查看栈顶元素,也就是把当前的坐标,以及此处的状态复制到另一个argnext中

  • 左边是否可行

先看左边能不能走
如果argnext.att<=2说明是刚进来,还没有试左边能不能走,因此进入判左语句中
左边能走我们,将数组该位置的值改为2,并且打印这个数组。
将argnext.x -= 1 后,判断这个点是不是墙、否越界数组,如果符合条件进入语句
进入语句就说明左边是能走的通的,然后我们将栈顶的也就是arg的状态arg.att改为3,说明我们已经走过左边,并且能走,
改过当前位置的状态之后,因为此处的左方是能走通的。因此我们需要将左方的坐标以及初始状态也压入栈内,
左边能走了,因为下面还有试其他方向的语句,我们让它每次只走一条路,因此我们需要continue来跳出本次循环,假如没有continue可能会使程序出错。

  • 上边是否可行

试过左边之后,试上边能不能走
如果argnext.att<=3说明是已经试过左边,然后来试上边。
上边能走我们,将数组该位置的值改为3,并且打印这个数组。
将argnext.y -= 1 后,判断这个点是不是墙、否越界数组,如果符合条件进入语句
进入语句就说明上边是能走的通的,然后我们将栈顶的也就是arg的状态arg.att改为4,说明我们已经走过上边,并且能走,
改过当前位置的状态之后,因为此处的上方是能走通的。因此我们需要将上方的坐标以及初始状态也压入栈内。然后跳出本次循环。

  • 右边是否可行

试过上边之后,试右边能不能走
如果argnext.att<=4说明是已经试过上边,然后来试右边。
右边能走我们,将数组该位置的值改为4,并且打印这个数组。
将argnext.y += 1 后,判断这个点是不是墙、否越界数组,如果符合条件进入语句
进入语句就说明右边是能走的通的,然后我们将栈顶的也就是arg的状态arg.att改为5,说明我们已经走过右边,并且能走,
改过当前位置的状态之后,因为此处的右方是能走通的。因此我们需要将上方的坐标以及初始状态也压入栈内。然后跳出本次循环。

  • 下边是否可行

试过右边之后,试下边能不能走
如果argnext.att<=5说明是已经试过右边,然后来试下边。
右边能走我们,将数组该位置的值改为5,并且打印这个数组。
将argnext.x += 1 后,判断这个点是不是墙、否越界数组,如果符合条件进入语句
进入语句就说明下边是能走的通的,然后我们将栈顶的也就是arg的状态arg.att改为6,说明我们已经走过下边,并且能走,
改过当前位置的状态之后,因为此处的下方是能走通的。因此我们需要将上方的坐标以及初始状态也压入栈内。然后跳出本次循环。

  • 出栈
    如果能走到最后一步说明这个点的上下左右都不能走,然后我们需要将它的状态置为1,也就是说,把它改成我们没走过的,这样就不影响后面寻找多条路时候我们不能再次走到这里的问题。
    然后将这个点Pop出栈。

循环结束条件

这样构成一个循环,结束条件为栈为空,结束条件为栈为空时,我们可以寻找迷宫的多个出口。

每次在循环中打印数组时,我门用一个system(“cls”);来清屏,实现一个看起来像是能动的迷宫(哈哈哈)

代码实现

  • 下面是代码实现
#pragma once
  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值